home *** CD-ROM | disk | FTP | other *** search
/ Power Programmierung / Power-Programmierung (Tewi)(1994).iso / magazine / lantimes / 90_03 / tserv.c < prev    next >
Text File  |  1990-01-08  |  11KB  |  399 lines

  1. /*-------------------------------------------------------------------------*
  2.  * tserv.c -- Tnet server program
  3.  *
  4.  * One computer in this network is designated the server machine. This
  5.  * program runs on that machine and only terminates in response
  6.  * to a keyboard request (``esc'' key) or a remote ``kill'' request.
  7.  * Network events are used to exchange data between the server and
  8.  * a remote node, and to control the operation of the server.
  9.  *
  10.  * T. Nolan - 11/20/89
  11.  *-------------------------------------------------------------------------*/
  12.  
  13. #include <dos.h>
  14. #include <process.h>
  15. #include <stdio.h>
  16. #include <stdlib.h>
  17. #include <string.h>
  18.  
  19. #include "netbios.h"
  20. #include "network.h"
  21.  
  22. static char buf[4096];        /* buffer for file read/write */
  23. int  verbose;                 /* set to 1 for diagnostic output */
  24. int  exitflag;                /* set to 1 to cause program exit */
  25. char local[16];               /* name of local network node */
  26.  
  27. /*-------------------------------------------------------------------------*/
  28. main(int ac, char **av)
  29. {
  30.    NCB    ncblist[SESSIONS];
  31.    ACTION actlist[SESSIONS];
  32.    int    i;
  33.  
  34.    if(!get_name(local))    /* find node name */
  35.    {
  36.       printf("error - NetBios not running\n");
  37.       exit(1);
  38.    }
  39.  
  40.    /* Issue receive datagrams on all of the ncbs. */
  41.  
  42.    for(i = 0; i < SESSIONS; i++)
  43.    {
  44.       clear_ncb(&ncblist[i]);
  45.       nw_recv_datagram(&actlist[i], sizeof(ACTION), &ncblist[i]);
  46.    }
  47.  
  48.    printf( "Tnet Server - T. Nolan 11/20/89 running on node %s\n", local);
  49.  
  50.    /* This is the main event loop. Any action results in
  51.     * an event appearing on the event list. Here it is
  52.     * dequeued, dispatched, and placed back on its free list.
  53.     */
  54.  
  55.    while(!exitflag)
  56.    {
  57.       if(kbhit())
  58.          key_handler(getch());
  59.  
  60.       for(i = 0; i < SESSIONS; i++)
  61.       {
  62.          if(ncblist[i].cmdcplt != 0xff)
  63.          {
  64.             net_handler(&ncblist[i], &actlist[i]);
  65.             clear_ncb(&ncblist[i]);
  66.             nw_recv_datagram(&actlist[i], sizeof(ACTION), &ncblist[i]);
  67.          }
  68.       }
  69.  
  70.    }
  71.  
  72.    /* Cancel all outstanding netbios requests and exit. */
  73.  
  74.    for(i = 0; i < SESSIONS; i++)
  75.       nb_cancel(&ncblist[i]);
  76.    exit(0);
  77. }
  78.  
  79. /*-------------------------------------------------------------------------*/
  80. key_handler(int keych)                /* handle local keyboard action */
  81. {
  82.    switch(tolower(keych))
  83.    {
  84.       case '\033' :
  85.  
  86.          exitflag = 1;
  87.          break;
  88.  
  89.       case 'v' :
  90.  
  91.          verbose = !verbose;
  92.          if(verbose)
  93.             diag("verbose mode\n");
  94.          break;
  95.  
  96.       default :
  97.  
  98.          diag("unrecognized key char %x\n", keych);
  99.          break;
  100.    }
  101. }
  102.  
  103. /*-------------------------------------------------------------------------*/
  104. net_handler(NCB *ncb, ACTION *cmd)           /* handle network action */
  105. {
  106.    char *node = ncb->callname;   /* point to remote requesting node */
  107.  
  108.    switch(cmd->type)
  109.    {
  110.       case NET_CNCT :
  111.  
  112.          net_cnct(node, cmd);
  113.          break;
  114.  
  115.       case NET_GET :
  116.  
  117.          net_get(node, cmd);
  118.          break;
  119.  
  120.       case NET_PUT :
  121.  
  122.          net_put(node, cmd);
  123.          break;
  124.  
  125.       case NET_DIR :
  126.  
  127.          net_dir(node, cmd);
  128.          break;
  129.  
  130.       case NET_CHD :
  131.  
  132.          net_chd(node, cmd);
  133.          break;
  134.  
  135.       case NET_DEL :
  136.  
  137.          net_del(node, cmd);
  138.          break;
  139.  
  140.       case NET_REMOTE :
  141.  
  142.          net_remote(node, cmd);
  143.          break;
  144.  
  145.       case NET_BYE :
  146.  
  147.          exitflag = 1;
  148.          break;
  149.  
  150.       default :
  151.  
  152.          printf("Unrecognized network command type %d\n",cmd->type);
  153.          cmd->code = NET_ERR;
  154.          send_datagram(node, cmd, sizeof(ACTION));
  155.          break;
  156.    }
  157. }
  158.  
  159. /*-------------------------------------------------------------------------*/
  160. diag(a, b, c, d, e, f, g, h, i, j)               /* diagnostic output */
  161. {
  162.    if(!verbose)
  163.       return;     /* only in verbose mode */
  164.    printf((char *) a, b, c, d, e, f, g, h, i, j);
  165. }
  166.  
  167. /*-------------------------------------------------------------------------*/
  168. net_cnct(char *node, ACTION *cmd)       /* accept a remote connection */
  169. {
  170.    diag("net_cnct %s\n", node);
  171.    cmd->code = NET_ACK;
  172.    strncpy(cmd->name, node, 16);
  173.    send_datagram(node, cmd, sizeof(ACTION));
  174. }
  175.  
  176. /*-------------------------------------------------------------------------*/
  177. net_get(char *node, ACTION *cmd)       /* handle request to get files */
  178. {
  179.    FILE *fp;
  180.    int lsn = 0;
  181.    int len;
  182.    struct find_t info;
  183.    int found;
  184.    char fname[80];
  185.    char *dir_end;
  186.  
  187.    diag("net_get file %s node %s\n", cmd->name, node);
  188.    found = !_dos_findfirst(cmd->name, 0, &info);
  189.    strcpy(fname, cmd->name);     /* copy file name */
  190.    dir_end = strrchr(fname, '\\');     /* locate last '\' char */
  191.    if(!dir_end)            /* none there... */
  192.       dir_end = fname;     /* so no directory string */
  193.    else              /* otherwise.. */
  194.       dir_end++;        /* point one char past '\' */
  195.  
  196.    while(found)
  197.    {
  198.       cmd->size = info.size;     /* extract file size */
  199.       strcpy(cmd->name, info.name); /* send name w/o directory */
  200.       *dir_end = '\0';     /* prepare to concat fname */
  201.       strcat(fname, info.name);  /* .. onto end of dir string */
  202.       if((fp = fopen(fname, "rb")) == NULL) /* now open the file */
  203.       {
  204.          diag("can't open file %s\n", fname);
  205.          break;
  206.       }
  207.       cmd->code = NET_ACK;
  208.       send_datagram(node, cmd, sizeof(ACTION));
  209.       diag("sending file %s", fname);
  210.       while(!lsn)
  211.          lsn = call(node, local);
  212.  
  213.       while(cmd->size > 0)
  214.       {
  215.          diag(".");
  216.          len = fread(buf, 1, sizeof(buf), fp);
  217.          send(lsn, buf, len);
  218.          cmd->size -= len;
  219.       }
  220.       fclose(fp);
  221.       diag("\n");
  222.       found = !_dos_findnext(&info);
  223.       receive(lsn, 0, 0);        /* wait for ACK */
  224.    }
  225.  
  226.    cmd->code = NET_ERR;
  227.    send_datagram(node, cmd, sizeof(ACTION));
  228.    receive(lsn, 0, 0);           /* wait for hangup */
  229. }
  230.  
  231. /*-------------------------------------------------------------------------*/
  232. net_put(char *node, ACTION *cmd)       /* handle request to put files */
  233. {
  234.    FILE *fp;
  235.    int lsn = 0;
  236.    int len;
  237.  
  238.    diag("net_put file %s size %ld node %s\n", cmd->name, cmd->size, node);
  239.  
  240.    fp = fopen(cmd->name, "wb");
  241.  
  242.    if(!fp)
  243.    {
  244.       diag("error opening file\n");
  245.       cmd->code = NET_ERR;
  246.       send_datagram(node, cmd, sizeof(ACTION));
  247.       return;
  248.    }
  249.  
  250.    cmd->code = NET_ACK;
  251.    send_datagram(node, cmd, sizeof(ACTION));
  252.  
  253.    while(!lsn)
  254.       lsn = call(node, local);
  255.  
  256.    diag("receiving file %s", cmd->name);
  257.    while(cmd->size > 0)
  258.    {
  259.       diag(".");
  260.       len = receive(lsn, buf, sizeof(buf));
  261.       if(fp)
  262.          fwrite(buf, 1, len, fp);
  263.       cmd->size -= len;
  264.    }
  265.    diag("\n");
  266.    fclose(fp);
  267.    hangup(lsn);
  268. }
  269.  
  270. /*-------------------------------------------------------------------------*/
  271. net_chd(char *node, ACTION *cmd)          /* handle req to change dir */
  272. {
  273.    int ret = 0;
  274.    int dum;
  275.    char *cp;
  276.    int drive;
  277.  
  278.    diag("net_chd: path %s\n", cmd->name);
  279.  
  280.    cp = strchr(cmd->name, ':');     /* locate drive specifier, if any */
  281.    if(cp)               /* if there is one.. */
  282.    {
  283.       drive = toupper(cp[-1]) - 'A' + 1;
  284.       _dos_setdrive(drive, &dum);   /* set the drive */
  285.       if(cp[1])         /* if there is a directory spec... */
  286.          ret = chdir(cmd->name); /* set the directory too */
  287.    }
  288.    else
  289.       if(*cmd->name)       /* no drive, but a directory... */
  290.          ret = chdir(cmd->name); /* set the directory */
  291.  
  292.    getcwd(cmd->name, sizeof(cmd->name));  /* now get current directory */
  293.    cmd->code = (ret) ? NET_ERR : NET_ACK; /* set success or error flag */
  294.    send_datagram(node, cmd, sizeof(ACTION)); /* send cwd back */
  295. }
  296.  
  297. /*-------------------------------------------------------------------------*/
  298. net_dir(char *node, ACTION *cmd)          /* handle directory request */
  299. {
  300.    char *tmpfile;
  301.    char *dos;
  302.    char arg[80];
  303.    FILE *fp;
  304.    int len;
  305.    int lsn = 0;
  306.  
  307.    diag("net_dir: node=%s, cmd=%s\n",node, cmd->name);
  308.  
  309.    tmpfile = tempnam(NULL,"tnet");        /* make unique name */
  310.    strcpy(arg, "dir/w ");           /* form a command... */
  311.    strcat(arg, cmd->name);          /*     of the form   */
  312.    strcat(arg, ">");          /*  dir file > tmp   */
  313.    strcat(arg, tmpfile);
  314.    dos = getenv("COMSPEC");         /* find command.com */
  315.    spawnl(P_WAIT, dos, dos, "/C", arg, NULL);   /* spawn w/ cmd line */
  316.  
  317.    if((fp = fopen(tmpfile, "rb")) == NULL)      /* open temp file */
  318.    {
  319.       printf("can't open %s\n",tmpfile);  /* something's wrong */
  320.       cmd->code = NET_ERR;       /* nak the request */
  321.       send_datagram(node, cmd, sizeof(ACTION));
  322.       return;
  323.    }
  324.  
  325.    cmd->size = filelength(fileno(fp));    /* get dir length */
  326.    cmd->code = NET_ACK;          /* ack the request */
  327.    send_datagram(node, cmd, sizeof(ACTION));
  328.    while(!lsn)
  329.       lsn = call(node, local);      /* call remote node */
  330.  
  331.    while(cmd->size > 0)          /* send the file */
  332.    {
  333.       len = fread(buf, 1, sizeof(buf), fp);
  334.       send(lsn, buf, len);
  335.       cmd->size -= len;
  336.    }
  337.  
  338.    fclose(fp);             /* close it */
  339.    unlink(tmpfile);           /* delete it */
  340.    receive(lsn, 0, 0);           /* wait for hang up */
  341. }
  342.  
  343. /*-------------------------------------------------------------------------*/
  344. net_del(char *node, ACTION *cmd)        /* handle req to delete files */
  345. {
  346.    struct find_t info;
  347.    int found;
  348.    char *c;
  349.    int nfiles = 0;
  350.    char cwd[60], fname[70];
  351.  
  352.    diag("net_del file %s node %s\n", cmd->name, node);
  353.    c = strrchr(cmd->name,'\\');
  354.    if(c)
  355.       strncpy(cwd, cmd->name, c - cmd->name);
  356.    else
  357.       cwd[0]='\0';
  358.  
  359.    found = !_dos_findfirst(cmd->name, _A_NORMAL, &info);
  360.    while(found)
  361.    {
  362.       strcpy(fname, cwd);
  363.       strcat(fname, info.name);
  364.       printf("unlinking %s\n",fname);
  365.       if(!unlink(fname))
  366.          nfiles++;
  367.       found = !_dos_findnext(&info);
  368.    }
  369.    cmd->code = (nfiles) ? NET_ACK : NET_ERR;
  370.    cmd->size = nfiles;        /* send # files deleted */
  371.    send_datagram(node, cmd, sizeof(ACTION));
  372. }
  373.  
  374. /*-------------------------------------------------------------------------*/
  375. net_remote(char *node, ACTION *cmd)         /* req to execute command */
  376. {
  377.    int i;
  378.    int ac;
  379.    char *av[10];
  380.    char *bp;
  381.  
  382.    av[0] = getenv("COMSPEC"); /* 1st arg is command.com pathname */
  383.    av[1] = "/C";        /* 2nd arg is /C (transient command) */
  384.    ac = cmd->size + 2;     /* fill in command args */
  385.    for(i = 2, bp = cmd->name; i < ac; i++)
  386.    {
  387.       av[i] = bp;
  388.       bp += strlen(bp) + 1;
  389.    }
  390.    av[ac] = 0;       /* terminate parameter list */
  391.  
  392.    diag("net_remote node=%s ac=%d", node, ac);
  393.    for(i = 0; i < ac; i++)
  394.       diag(" %s", av[i]);
  395.  
  396.    cmd->code = spawnv(P_WAIT, av[0], av);    /* issue command */
  397.    send_datagram(node, cmd, sizeof(ACTION)); /* return exit code */
  398. }
  399.